package com.peas.platform.common.core.configuration;

import cn.hutool.core.text.CharSequenceUtil;
import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@ConditionalOnNacosDiscoveryEnabled
@Slf4j
public class NacosApplicationRunner implements ApplicationRunner {

    @Value("${spring.shutdown:25}")
    private Integer shutdown;

    @Resource
    private ApplicationContext ac;
    @Resource
    private NacosServiceManager nacosServiceManager;

    @SneakyThrows
    public void shutdownHook() {
        log.info("正在尝试向nacos注销服务。");
        String discovery = ac.getEnvironment().getProperty("spring.cloud.nacos.discovery.enabled");
        if (CharSequenceUtil.equalsIgnoreCase("false", discovery)) {
            log.info("未开启nacos注册服务，无需注销。");
            return;
        }
        NacosDiscoveryProperties nacosDiscoveryProperties = ac.getBean(NacosDiscoveryProperties.class);
        String serviceName = nacosDiscoveryProperties.getService();
        String groupName = nacosDiscoveryProperties.getGroup();
        String clusterName = nacosDiscoveryProperties.getClusterName();
        String ip = nacosDiscoveryProperties.getIp();
        int port = nacosDiscoveryProperties.getPort();
        log.info("deregister from nacos, serviceName:{}, groupName:{}, clusterName:{}, ip:{}, port:{}", serviceName, groupName, clusterName, ip, port);
        try {
            nacosServiceManager.getNamingService().deregisterInstance(serviceName, groupName, ip, port, clusterName);
            log.info("nacos注销服务完毕，{}秒后服务停止", shutdown);
            Thread.sleep(shutdown * 1000);
        } catch (InterruptedException e) {
            log.error("nacos服务注销出现异常。", e);
            Thread.currentThread().interrupt();
            throw e;
        } catch (NacosException e) {
            log.error("nacos服务注销出现异常。", e);
            throw e;
        }
    }

    @Override
    public void run(ApplicationArguments args) {
        log.info("add shutdown hook for nacos.");
        log.info("class of ApplicationContext:{}", ac.getClass().getName());// org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
        Runtime.getRuntime().addShutdownHook(new Thread(this::shutdownHook));
    }

}
